package net.wangds.common.web.fileupload.ctrl;

import net.wangds.common.web.fileupload.ctrl.from.FileIds;
import net.wangds.common.web.fileupload.module.FileBytes;
import net.wangds.common.web.fileupload.module.FileUploadData;
import net.wangds.common.web.fileupload.module.UploadFileEntity;
import net.wangds.common.web.fileupload.service.FileUploadServ;
import net.wangds.common.web.fileupload.viewmodel.form.FileUploadForm;
import net.wangds.log.helper.LogHelper;
import net.wangds.utils.JsonUtils;
import net.wangds.web.entrypoint.BaseMultipleResp;
import net.wangds.web.entrypoint.BaseResp;
import net.wangds.web.utils.HttpDownloadHeaderUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * .
 * <p></p>
 *
 * @author 王东石 2020/5/27 19:57.
 */
@RestController
@RequestMapping("/files")
public class FileUploadCtrl {

    @Autowired
    @SuppressWarnings("unused")
    private FileUploadServ mmServUpld;

    @RequestMapping(value="/uploadForm", method = RequestMethod.POST)
    @SuppressWarnings("unused")
    public void uploadFile(MultipartHttpServletRequest req, HttpServletResponse resp){
        Iterator<String> filenames = req.getFileNames();
        if(filenames==null){
            return;
        }

        filenames.forEachRemaining(filename->{
            try {
                MultipartFile file = req.getFile(filename);
                if(file==null){
                    return;
                }
                byte[] bytes = file.getBytes();
                String name = file.getOriginalFilename();
                String type = file.getContentType();
                long size = file.getSize();
                long tm = System.currentTimeMillis();

                mmServUpld.onUpload(FileUploadData.builder()
                        .content(bytes)
                        .type(type)
                        .size(size)
                        .filename(name)
                        .fileTm(tm)
                        .build());

            }catch (Exception ex){
                LogHelper.error(ex);
            }
        });
    }

    @RequestMapping(value="/uploadFormReturnJson", method = RequestMethod.POST)
    @SuppressWarnings("unused")
    public void uploadFileReturnJson(MultipartHttpServletRequest req, HttpServletResponse resp){
        Iterator<String> filenames = req.getFileNames();
        if(filenames==null){
            return;
        }

        List<Map<String, Object>> res = new ArrayList<>();

        filenames.forEachRemaining(filename->{
            // LogHelper.dev("filename："+filename);
            try {
                MultipartFile file = req.getFile(filename);

                if(file==null){
                    return;
                }
                byte[] bytes = file.getBytes();
                String type = file.getContentType();
                String name = file.getOriginalFilename();
                long size = file.getSize();
                long tm = System.currentTimeMillis();

                mmServUpld.onUpload(FileUploadData.builder()
                        .content(bytes)
                        .type(type)
                        .size(size)
                        .filename(name)
                        .fileTm(tm)
                        .build()).ifPresent(f->{

                            Map<String, Object> m = new HashMap<>();
                            m.put("id", f.getId());
                            m.put("filename", f.getFilename());
                            m.put("type", f.getType());
                            m.put("size", f.getSize());
                            res.add(m);

                });

            }catch (Exception ex){
                LogHelper.error(ex);
            }
        });

        resp.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
        try(OutputStream os=resp.getOutputStream()){
            os.write(JsonUtils.toJsonStr(res).getBytes(StandardCharsets.UTF_8));
            os.flush();
        } catch (IOException e) {
            LogHelper.error(e);
        }
    }



    @RequestMapping(value="/uploadFile", method = RequestMethod.POST)
    @SuppressWarnings("unused")
    public BaseResp<String> uploadFile(
            @RequestBody FileUploadForm form
    ){

        LogHelper.dev(()->"/uploadFile:"+ JsonUtils.toJsonStr(form.getFilename()));

        BaseResp<String> res = BaseResp.<String>of(null).code(-1);

        mmServUpld.onUpload(FileUploadForm.builder()
                .content(form.getContent())
                .filename(form.getFilename())
                .fileTm(form.getFileTm())
                .type(form.getType())
                .size(form.getSize())
                .build()).ifPresent(f-> res.body(f.getId()).code(0));

        return res;
    }

    @RequestMapping(value="/download/{id}", method = RequestMethod.GET)
    @SuppressWarnings("unused")
    public void downloadFile(
            @PathVariable("id") String fileId,
            HttpServletRequest req,
            HttpServletResponse resp
    ){
        FileBytes file = mmServUpld.loadFile(fileId);

        HttpDownloadHeaderUtils.writeAttachmentHeaders(file.getFilename(), req, resp);

        try(OutputStream os = resp.getOutputStream()){
            os.write(file.getContent());
            os.flush();
        } catch (IOException e) {
            LogHelper.error(e);
        }

    }


    @RequestMapping(value="/file/{id}", method = RequestMethod.GET)
    @SuppressWarnings("unused")
    public void loadFile(
            @PathVariable("id") String fileId,
            HttpServletRequest req,
            HttpServletResponse resp
    ){
        FileBytes file = mmServUpld.loadFile(fileId);

        HttpDownloadHeaderUtils.writeFileHeaders(file.getFilename(), file.getType(), req, resp);

        try(OutputStream os = resp.getOutputStream()){
            os.write(file.getContent());
            os.flush();
        } catch (IOException e) {
            LogHelper.error(e);
        }

    }

    @RequestMapping(value = "/listByIds", method = RequestMethod.POST)
    public BaseMultipleResp<UploadFileEntity> findByIds(
            @RequestBody FileIds ids
    ){
        if(ids==null
                || (StringUtils.isBlank(ids.getFileIds())
                && CollectionUtils.isEmpty(ids.getFileIdList()))) {
            BaseMultipleResp<UploadFileEntity> res = BaseMultipleResp.list(Collections.emptyList());
            res.code(0).msg("输入为空");
            return res;
        }

        List<String> fileList = ids.getFileIdList();
        if(CollectionUtils.isEmpty(fileList)){
            fileList = new ArrayList<>();
        }
        String strIds = ids.getFileIds();
        if(StringUtils.isNotEmpty(strIds)){

            fileList.addAll(
                Arrays.stream(strIds.split(","))
                    .collect(Collectors.toList())
            );

        }

        List<UploadFileEntity> files = mmServUpld.findInIds(fileList);

        return BaseMultipleResp.list(files);

    }


}
